
package com.hlkj.pay.app.merchant.ext.impl.leshua.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.leshua.LeshuaPayScenePayOrderExtPt;
import com.hlkj.pay.app.merchant.ext.impl.leshua.constant.LeshuaPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.leshua.constant.LeshuaPayExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.LeshuaPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.resp.LeshuaMicroPayRes;
import com.hlkj.pay.app.merchant.ext.impl.leshua.handler.LeshuaPayCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.yeepay.dto.YeePayAppChannelParams;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.vo.order.req.PayOrderCommonParamReq;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 公众号统一下单
 *
 * @author HlpayTeam
 * @date 2024/11/18 13:07
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = LeshuaPayExtConstant.SCAN_PAY)
public class LeshuaPayScanPayOrderExtPt extends LeshuaPaySceneCommonPayOrder implements LeshuaPayScenePayOrderExtPt {

    private final LeshuaPayCommonParamsHandle leshuaPayCommonParamsHandle;

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {

        log.info("乐刷 SCAN_PAY 请求参数:{}", JsonUtils.toJsonString(channelPayOrderContext));
        CommonResult<LeshuaPayConfig> leshuaPayConfigCommonResult = leshuaPayCommonParamsHandle.leshuaPayConfig(channelPayOrderContext.getProviderChannelConfigDO(),
                channelPayOrderContext.isTest());
        if (!leshuaPayConfigCommonResult.isSuccess()) {
            channelPayOrderContext.setRemark(leshuaPayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        // 支付订单信息
        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        // 支付方式信息
        PayWayDO payWayDO = channelPayOrderContext.getPayWayDO();
        // 商户通道信息
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        // 乐刷配置信息
        LeshuaPayConfig leshuaPayConfig = leshuaPayConfigCommonResult.getData();
        // 额外参数信息
        PayOrderCommonParamReq.Extra extra = channelPayOrderContext.getExtra();
        if (extra == null || !StringUtils.hasText(extra.getAuthCode())) {
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
            channelPayOrderContext.setRemark("乐刷 "+ PayEnums.PAY_TYPE.fromByCode(payWayDO.getType()).getType() +" 提交 SCAN_PAY 支付 没有提交AuthCode");
            return;
        }

        try {
            YeePayAppChannelParams yeeAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), YeePayAppChannelParams.class);

            String payway = leshuaPayCommonParamsHandle.getPayWay(payWayDO);
            if(StrUtil.isEmpty(payway)){
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark("乐刷提交 SCAN_PAY 支付 支付类型: "+payWayDO.getType()+" 不支持");
                return;
            }

            String getPayChannel = leshuaPayCommonParamsHandle.getPayChannel(payWayDO);
            if(StrUtil.isEmpty(getPayChannel)){
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark("乐刷提交SCAN_PAY支付 渠道类型: "+payWayDO.getType()+" 不支持");
                return;
            }

            Map<String,String> reqData = new HashMap<>();
            reqData.put("service","upload_authcode");
            reqData.put("auth_code",extra.getAuthCode());
            reqData.put("merchant_id", yeeAppChannelParams.getSubMchId());
            reqData.put("third_order_id", payOrderDO.getPayOrderNo());
            reqData.put("amount",leshuaPayCommonParamsHandle.yuanToFen(payOrderDO.getAmount().toString(),2));
            reqData.put("notify_url",channelPayOrderContext.getNotifyUrl());
            reqData.put("client_ip",payOrderDO.getClientIp());

            // 终端信息
            Map<String,String> terminal_info = new HashMap<>();
            terminal_info.put("device_type ","10");
            terminal_info.put("device_id", RandomUtil.randomString(12));
            reqData.put("terminal_info",JSONUtil.toJsonStr(terminal_info));

            reqData.put("body",payOrderDO.getSubject());

            log.info("乐刷提交SCAN_PAY支付 请求参数:{}", JSONUtil.toJsonStr(reqData));
            String result = leshuaPayCommonParamsHandle.requestPostApi(LeshuaPayConstant.ORDER_GATEWAY_RUL,reqData,leshuaPayConfig);
            log.info("乐刷提交SCAN_PAY支付 返回参数:{}", result);
            if(StrUtil.isEmpty(result)){
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark("乐刷提交SCAN_PAY支付请求失败");
                return;
            }
            // 结果转对象
            LeshuaMicroPayRes microPayRes = JSONUtil.toBean(result,LeshuaMicroPayRes.class);
            // 通信状态和支付状态都成功
            if("0".equals(microPayRes.getResp_code()) && "0".equals(microPayRes.getResult_code())){
                channelPayOrderContext.setChannelOrderNo(microPayRes.getOut_transaction_id());
                channelPayOrderContext.setChannelOrderId(microPayRes.getChannel_order_id());
                channelPayOrderContext.setInsOrderNo(microPayRes.getLeshua_order_id());
            }else{
                String respDesc = microPayRes.getResp_msg();
                if(!"0".equals(microPayRes.getResult_code())){
                    respDesc = microPayRes.getError_msg();
                }
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark(respDesc);
            }
        }catch (Exception e) {
            e.printStackTrace();
            channelPayOrderContext.setRemark("乐刷提交SCAN_PAY支付 请求失败, error: " + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonCloseChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelClosePayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonQueryRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return true;
    }

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        return CommonResult.success();
    }
}
